/* Configuration example
  <filter>
    <filter-name>HotlinkingFilter</filter-name>
    <filter-class>by.ad.filter.HotlinkingFilter</filter-class>
    <init-param>
      <param-name>GoodReferers</param-name>
      <param-value>addis-abeba.ad.by,localhost,127.0.0.1</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>HotlinkingFilter</filter-name>
    <url-pattern>/*.jpg</url-pattern>
  </filter-mapping>
*/
package by.ad.filter;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import static by.ad.HttpUtils.REFERER;
import static by.ad.HttpUtils.isHTTP11;

public class HotlinkingFilter 
  implements Filter 
{
  public void init(final FilterConfig filterConfig)
    throws ServletException
  {
    this.goodReferers.addAll(Arrays.asList(
      filterConfig.getInitParameter("GoodReferers").split(",")));
  }

  public void doFilter(final ServletRequest req, final ServletResponse resp,
    final FilterChain filterChain)
      throws IOException, ServletException
  {
    if (req instanceof HttpServletRequest && resp instanceof HttpServletResponse) {
      final String referer = ((HttpServletRequest) req).getHeader(REFERER);
      if (referer != null && !goodReferers.contains(referer)) {

// TODO CSRF protection - deny POST requests from 3rd-party domains
//      check POST && ("Referer" || "X-Requested-With")

        ((HttpServletResponse) resp).sendError(
          isHTTP11(req) ? HttpServletResponse.SC_PRECONDITION_FAILED : HttpServletResponse.SC_FORBIDDEN, 
          "No hotlinking");
        
        // TODO store log to DB and show report on /techstat page
        
        return;
      }
    }
      
    filterChain.doFilter(req, resp);    
  }

  public void destroy() {}
    
  private final Set<String> goodReferers = new HashSet<String>();
}
